# Environment
MKDIR=mkdir
CP=cp
GREP=grep
NM=nm
CCADMIN=CCadmin
RANLIB=ranlib
CC=gcc
CCC=g++
CXX=g++
FC=gfortran
AS=as

# Macros
ifeq ($(CND_PLATFORM),)
CND_PLATFORM=GNU-Linux
endif
ifeq ($(CND_CONF),)
CND_CONF=Release
endif
ifeq ($(CND_DISTDIR),)
CND_DISTDIR=dist
endif
ifeq ($(CND_BUILDDIR),)
CND_BUILDDIR=.build
endif

# Object Directory
ifeq ($(CODEDIRS),)
CODEDIRS=.
endif
ifeq ($(TARGETDIR),)
TARGETDIR=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}
endif
ifeq ($(TARGETNAME),)
TARGETNAME=a
endif
ifeq ($(PROJTYPE),)
PROJTYPE=out
endif
ifeq ($(OBJECTDIR),)
OBJECTDIR:=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}
endif

ifeq ($(PROJTYPE),out)
TARGETPREFIX=
TARGETEXT=.out
else ifeq ($(PROJTYPE),a)
TARGETPREFIX=lib
TARGETEXT=.a
else ifeq ($(PROJTYPE),so)
TARGETPREFIX=lib
TARGETEXT=.so
endif

ifeq ($(INCLUDEDIRS),)
INCLUDEDIRS=
endif
ifeq ($(LINKLIBDIRS),)
LINKLIBDIRS=
endif
ifeq ($(LINKLIBNAMES),)
LINKLIBNAMES=
endif
ifeq ($(LINKSTATICLIBNAMES),)
LINKSTATICLIBNAMES=
endif
ifeq ($(COMPILEOPT),)
COMPILEOPT=
endif
ifeq ($(LINKOPT),)
LINKOPT=
endif

ALLFILES := $(foreach dir, $(CODEDIRS), $(shell find $(dir) -maxdepth 100 -type f -name '*.cpp'))
#ALLFILES := $(foreach dir,$(ALLDIRS),$(wildcard $(dir)/*.cpp))
ALLFILES += $(ADDITIONALFILES)
ALLOBJS := $(patsubst %.cpp,%.o, $(ALLFILES))
ALLOBJSPATH := $(foreach n, ${ALLOBJS}, ${OBJECTDIR}$(abspath $(n)))
TARGETOUT:=${TARGETDIR}/$(TARGETPREFIX)$(TARGETNAME)$(TARGETEXT)
INCLUDEOPT:=$(foreach n, ${INCLUDEDIRS}, -I${n})
LINKLIBOPT:=$(foreach n, ${LINKLIBDIRS}, -L${n}) 
LINKLIBOPT+=$(foreach n, ${LINKLIBNAMES}, -l${n})
LINKLIBOPT+=$(foreach n, ${LINKSTATICLIBNAMES}, -l:lib${n}.a)

ifeq ($(PROJTYPE),out)
ifneq ($(LINKLIBNAMES),)
DEPLIBS:=$(foreach dir, $(LINKLIBDIRS), $(foreach n, $(LINKLIBNAMES), $(wildcard $(dir)/lib$(n).so $(dir)/lib$(n).a)))
endif
ifneq ($(LINKSTATICLIBNAMES),)
DEPLIBS+=$(foreach dir, $(LINKLIBDIRS), $(foreach n, $(LINKSTATICLIBNAMES), $(wildcard $(dir)/lib$(n).a)))
endif

.PHONY:all
all: ${TARGETOUT}
	
$(TARGETOUT): ${ALLOBJSPATH} $(DEPLIBS)
	${MKDIR} -p ${TARGETDIR}
	${RM} ${TARGETOUT}
	$(LINK.cc) -o $(TARGETOUT) $(ALLOBJSPATH) $(LINKLIBOPT) $(LINKOPT)
	@echo *********Build $(TARGETOUT) Successful*********
else ifeq ($(PROJTYPE),a)
$(TARGETOUT): ${ALLOBJSPATH}
	${MKDIR} -p ${TARGETDIR}
	${RM} ${TARGETOUT}
	${AR} -rv ${TARGETOUT} ${ALLOBJSPATH} 
	$(RANLIB) ${TARGETOUT}
	@echo *********Build $(TARGETOUT) Successful*********
else ifeq ($(PROJTYPE),so)
$(TARGETOUT): ${ALLOBJSPATH}
	${MKDIR} -p ${TARGETDIR}
	${RM} ${TARGETOUT}
	$(LINK.cc) -o $(TARGETOUT) $(ALLOBJSPATH) -shared -fPIC $(LINKOPT)
	@echo *********Build $(TARGETOUT) Successful*********
endif

sinclude $(foreach n, $(ALLOBJSPATH), $(n).d)
$(ALLOBJSPATH):${OBJECTDIR}%.o : %.cpp
	${RM} "$@.d"
	${MKDIR} -p $(dir $@)
	$(COMPILE.cc) -MMD -MP -MF "$@.d" -o "$@" "$<" $(INCLUDEOPT) -Wall -Werror $(COMPILEOPT)

.PHONY:clean
clean:
	${RM} -r ${OBJECTDIR}
